<#
.SYNOPSIS
  lnmp k8s CLI
.DESCRIPTION
  lnmp k8s CLI
.EXAMPLE
  PS C:\> lnmp-k8s create development

.EXAMPLE
  PS C:\> lnmp-k8s create development --dry-run

.INPUTS

.OUTPUTS

.NOTES

#>
cd $PSScriptRoot

################################################################################

$KUBECTL_URL = "https://storage.googleapis.com/kubernetes-release/release"
$KUBECTL_URL = "https://mirror.azure.cn/kubernetes/kubectl"

################################################################################

if (!(Test-Path .env.ps1 )) {
  cp .env.example.ps1 .env.ps1
}

if (!(Test-Path .env )) {
  cp .env.example .env
}

if (!(Test-Path coreos/.env )) {
  cp coreos/.env.example coreos/.env
}

if (!(Test-Path wsl2/.env )) {
  cp wsl2/.env.example wsl2/.env
}

if (!(Test-Path wsl2/.env.ps1 )) {
  cp wsl2/.env.example.ps1 wsl2/.env.ps1
}

if (!(Test-Path systemd/.env )) {
  cp systemd/.env.example systemd/.env
}

. "$PSScriptRoot/.env.example.ps1"

if (Test-Path .env.ps1 ) {
  . "$PSScriptRoot/.env.ps1"
}

$k8s_current_context = kubectl config current-context

write-host "==> Kubernetes context is [ $k8s_current_context ]" -ForegroundColor Blue

Function print_info($message) {
  write-host "==> $message"
}

Function print_help_info() {
  echo "
Usage: lnmp-k8s.ps1 COMMAND

Commands:
  kubectl-install    Install kubectl
  kubectl-info       Get kubectl latest version info

  create             Deploy lnmp on k8s {ENVIRONMENT: development (default) | testing | staging | production} {OPTIONS}
  delete             Stop lnmp on k8s, keep data resource(pv and pvc) {ENVIRONMENT: development (default) | testing | staging | production}
  cleanup            Stop lnmp on k8s, and remove all resource(pv and pvc) {ENVIRONMENT: development (default) | testing | staging | production}

  helm-development   Install Helm LNMP In Development
  helm-testing       Install Helm LNMP In Testing
  helm-staging       Install Helm LNMP In Staging
  helm-production    Install Helm LNMP In Production

  dist-containerd-arm64
"
}

if (!(Test-Path systemd/.env)) {
  Copy-Item systemd/.env.example systemd/.env
}

if ($args.length -eq 0) {
  print_help_info
  exit
}

Function get_kubectl_version() {
  $url = "https://storage.googleapis.com/kubernetes-release/release/stable.txt"
  $url = "https://mirror.azure.cn/kubernetes/kubectl/stable.txt"
  return $KUBECTL_VERSION = $(curl.exe -fsSL $url)
}

Function _delete_lnmp($NAMESPACE = "lnmp") {
  kubectl -n $NAMESPACE delete deployment -l app=lnmp
  kubectl -n $NAMESPACE delete service -l app=lnmp
  kubectl -n $NAMESPACE delete secret -l app=lnmp
  kubectl -n $NAMESPACE delete configmap -l app=lnmp
  kubectl -n $NAMESPACE delete cronjob -l app=lnmp
}

Function _create_pvc($NAMESPACE = "lnmp") {
  kubectl -n $NAMESPACE apply -f deployment/pvc/lnmp-pvc.yaml
}

Function _create_hostpath($ENVIRONMENT = "development") {
  $items = "mysql-data", "nginx-data", "redis-data", "log", "registry-data"
  foreach ($item in $items) {
    mkdir -Force /Users/$env:username/.docker/Volumes/lnmp-$item-$ENVIRONMENT
  }
}

Function _create_pv($NAMESPACE = "lnmp", $ENVIRONMENT = "development") {
  # _create_hostpath $ENVIRONMENT

  Get-Content deployment/pv/lnmp-volume.windows.temp.yaml `
  | % { Write-Output `
      $_.Replace("/Users/username", "/Users/$env:username") `
  } `
  | % { Write-Output `
      $_.Replace("development", $ENVIRONMENT) `
  } `
  | kubectl apply -f -
}

Function _helm_lnmp($environment, $debug = 0) {
  cd helm

  if ($debug) {
    $opts = "--debug", "--dry-run"
  }

  Foreach ($item in $helm_services) {
    helm install ./$item `
      --name lnmp-$item-$environment `
      --namespace lnmp-$environment `
      --set APP_ENV=$environment `
      --set platform=windows `
      --set username=$env:username `
    $( Foreach ($opt in $opts) { echo $opt } )
  }

  cd $PSScriptRoot
}

$command, $others = $args

switch ($args[0]) {
  "kubectl-install" {
    $KUBECTL_VERSION = get_kubectl_version
    write-host $KUBECTL_VERSION
    $url = "${KUBECTL_URL}/${KUBECTL_VERSION}/bin/windows/amd64/kubectl.exe"
    if (Test-Path C:\bin\kubectl.exe) {
      print_info "kubectl already install"
      return
    }
    curl.exe -fsSL $url -o C:\bin\kubectl.exe
  }

  "kubectl-info" {
    $KUBECTL_VERSION = get_kubectl_version
    "==> Latest Stable Version is: $KUBECTL_VERSION
    "
  }

  "create" {
    if ( $k8s_current_context -ne "docker-desktop") {
      Write-Warning "
==> This Script ONLY Support [ K8S on Docker Desktop ] On Winodws

==> Check Kubernetes context [ docker-desktop ] ...

$(kubectl config get-contexts docker-desktop 2>&1 )

==> you can use kubernetes context [ docker-desktop ] by EXEC:

$ kubectl config use-context docker-desktop

"

      exit
    }

    $ENVIRONMENT = "development"
    $NAMESPACE = "lnmp"

    if ($others) {
      $ENVIRONMENT = $others.split(' ')[0]
      $_, $options = $others
    }

    if ($ENVIRONMENT -ne "development") {
      $NAMESPACE = "lnmp", $ENVIRONMENT -join '-'
    }

    "==> NAMESPACE is $NAMESPACE"
    "==> OPTIONS is $options"

    kubectl create namespace $NAMESPACE $options

    if ($NAMESPACE -ne "lnmp") {
      $items = "mysql", "redis", "php", "nginx"

      _create_pv $NAMESPACE $ENVIRONMENT $options
      # dont create pvc

      foreach ($item in $items) {
        (get-content deployment/$item/overlays/$ENVIRONMENT/kustomization.yaml) `
          -replace "# - hostpath.patch.yaml", "- hostpath.patch.yaml" `
        | Set-Content deployment/$item/overlays/$ENVIRONMENT/kustomization.yaml
      }

      foreach ($item in $items) {
        kubectl -n $NAMESPACE apply -k deployment/$item/overlays/$ENVIRONMENT/ $options
      }

      foreach ($item in $items) {
        "==> restore kustomization.yaml"
        git checkout -- deployment/$item/overlays/$ENVIRONMENT/kustomization.yaml
      }

      # kubectl -n $NAMESPACE apply -k deployment/nginx/overlays/windows/ $options

      return
    }

    kubectl get pvc/lnmp-app -n $NAMESPACE -o json > $null 2>&1

    if ($?) {
      "==> PVC exists, SKIP create PV and PVC"
    }
    else {
      _create_pv $NAMESPACE $ENVIRONMENT $options
      _create_pvc $NAMESPACE $options
    }

    $CONFIG_ROOT = "deployment/php/overlays/${ENVIRONMENT}/config"
    kubectl -n $NAMESPACE create configmap lnmp-php-conf `
      --from-file=php.ini=${CONFIG_ROOT}/ini/php.${ENVIRONMENT}.ini `
      --from-file=zz-docker.conf=${CONFIG_ROOT}/zz-docker.${ENVIRONMENT}.conf `
      --from-file=composer.config.json=${CONFIG_ROOT}/composer/config.${ENVIRONMENT}.json `
      --from-file=docker.ini=${CONFIG_ROOT}/conf.d/docker.${ENVIRONMENT}.ini `
      --dry-run -o yaml `
    | kubectl -n $NAMESPACE apply -f - $options
    kubectl -n $NAMESPACE label configmap lnmp-php-conf app=lnmp version=0.0.1 $options

    $CONFIG_ROOT = "deployment/mysql/overlays/${ENVIRONMENT}/config"
    kubectl -n $NAMESPACE create configmap lnmp-mysql-cnf `
      --from-file=docker.cnf=${CONFIG_ROOT}/docker.${ENVIRONMENT}.cnf `
      --dry-run -o yaml `
    | kubectl -n $NAMESPACE apply -f - $options
    kubectl -n $NAMESPACE label configmap lnmp-mysql-cnf app=lnmp version=0.0.1 $options

    $CONFIG_ROOT = "deployment/nginx/overlays/${ENVIRONMENT}/config"
    kubectl -n $NAMESPACE create configmap lnmp-nginx-conf `
      --from-file=nginx.conf=${CONFIG_ROOT}/nginx.${ENVIRONMENT}.conf `
      --dry-run -o yaml `
    | kubectl -n $NAMESPACE apply -f - $options
    kubectl -n $NAMESPACE label configmap lnmp-nginx-conf app=lnmp version=0.0.1 $options

    kubectl -n $NAMESPACE create configmap lnmp-nginx-conf.d `
      --from-file=deployment/configMap/nginx-conf-d `
      --dry-run -o yaml `
    | kubectl -n $NAMESPACE apply -f - $options
    kubectl -n $NAMESPACE label configmap lnmp-nginx-conf.d app=lnmp version=0.0.1 $options

    # kubectl -n $NAMESPACE create secret generic lnmp-mysql-password `
    #  --from-literal=password=mytest $options

    kubectl -n $NAMESPACE apply -f deployment/lnmp-configMap.${ENVIRONMENT}.yaml $options

    kubectl -n $NAMESPACE apply -f deployment/lnmp-secret.${ENVIRONMENT}.yaml $options

    kubectl -n $NAMESPACE apply -f deployment/mysql/base/lnmp-mysql.yaml $options

    kubectl -n $NAMESPACE apply -f deployment/redis/base/lnmp-redis.yaml $options

    kubectl -n $NAMESPACE apply -f deployment/php/base/lnmp-php7.yaml $options

    kubectl -n $NAMESPACE apply -f deployment/nginx/base/lnmp-nginx.yaml $options

    kubectl -n $NAMESPACE apply -f deployment/nginx/base/lnmp-nginx.service.yaml $options

  }

  "delete" {
    $ENVIRONMENT = "development"
    $NAMESPACE = "lnmp"

    if ($others) {
      $ENVIRONMENT = $others.split(' ')[0]
      $_, $options = $others
    }

    if ($ENVIRONMENT -ne "development") {
      $NAMESPACE = "lnmp", $ENVIRONMENT -join '-'
    }

    "==> NAMESPACE is $NAMESPACE"

    _delete_lnmp $NAMESPACE
  }

  "cleanup" {
    $ENVIRONMENT = "development"
    $NAMESPACE = "lnmp"

    if ($others) {
      $ENVIRONMENT = $others.split(' ')[0]
      $_, $options = $others
    }

    if ($ENVIRONMENT -ne "development") {
      $NAMESPACE = "lnmp", $ENVIRONMENT -join '-'
    }

    "==> NAMESPACE is $NAMESPACE"
    _delete_lnmp $NAMESPACE

    kubectl -n $NAMESPACE delete pvc -l app=lnmp

    if ($ENVIRONMENT -eq 'development') {
      kubectl delete pv -l app=lnmp
    }
    else {
      "==> SKIP delete PV"
    }

    kubectl -n $NAMESPACE delete ingress -l app=lnmp
  }

  "helm-development" {
    _helm_lnmp development $args[1]
  }

  "helm-testing" {
    _helm_lnmp testing $args[1]
  }

  "helm-staging" {
    _helm_lnmp staging $args[1]
  }

  "helm-production" {
    _helm_lnmp production $args[1]
  }

  "dist-containerd-arm64" {
    if (Test-Path containerd-nightly.linux-arm64) {
      rm -r -force containerd-nightly.linux-arm64
    }

    Expand-Archive -Path linux_arm64.zip -DestinationPath containerd-nightly.linux-arm64
    mkdir containerd-nightly.linux-arm64/bin | out-null
    mv containerd-nightly.linux-arm64/containerd* containerd-nightly.linux-arm64/bin/
    mv containerd-nightly.linux-arm64/ctr containerd-nightly.linux-arm64/bin/
    tar -zcvf containerd-nightly.linux-arm64.tar.gz containerd-nightly.linux-arm64
    rm -r -force containerd-nightly.linux-arm64
  }

  Default {
    Write-Warning "Command not found"
  }

}
